use sqlx::{Error, FromRow, SqlitePool};

#[derive(Debug, FromRow)]
struct User {
    id: Option<i32>,
    name: Option<String>,
    email: Option<String>,
    age: Option<i32>,  // 添加一个整数字段作为示例
}

macro_rules! crud {
    ($struct_name:ident, $table_name:expr, [$($field:ident: $field_type:ty),*]) => {
        impl $struct_name {
            // 创建记录，跳过 None 的字段
            pub async fn create(&mut self, pool: &SqlitePool) -> Result<(), Error> {
                let mut fields = vec![];
                let mut values = vec![];
                let mut binds: Vec<(String, Box<dyn sqlx::Encode<'_> + Send + 'static>)> = vec![];

                $(
                    if let Some(ref val) = self.$field {
                        fields.push(stringify!($field)); // 使用字段名作为数据库字段名
                        values.push("?");
                        binds.push((stringify!($field).to_string(), Box::new(val.clone()) as Box<dyn sqlx::Encode<'_> + Send>)); // 绑定值
                    }
                )*

                let query = format!(
                    "INSERT INTO {} ({}) VALUES ({})",
                    $table_name,
                    fields.join(", "),
                    values.join(", ")
                );

                let mut query_builder = sqlx::query(&query);
                for bind in binds {
                    query_builder = query_builder.bind(bind);
                }

                let result = query_builder.execute(pool).await?;
                self.id = Some(result.last_insert_rowid() as i32); // 设置生成的ID

                Ok(())
            }

            // 更新记录，跳过 None 的字段

        }
    };
}

// 使用宏生成 User 结构体的CRUD操作
crud!(User, "users", [name: Option<String>, email: Option<String>, age: Option<i32>]);
